package org.fujay.langchain4jserver.interfaces.api;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.fujay.commons.core.result.R;
import org.fujay.langchain4jserver.application.command.StartConversationCommand;
import org.fujay.langchain4jserver.application.dto.ConversationDetailDTO;
import org.fujay.langchain4jserver.application.dto.ConversationSummaryDTO;
import org.fujay.langchain4jserver.application.dto.SendMessageRequest;
import org.fujay.langchain4jserver.application.service.ConversationService;
import org.fujay.langchain4jserver.domain.application.vo.AppId;
import org.fujay.langchain4jserver.domain.conversation.vo.ConversationId;
import org.fujay.langchain4jserver.domain.conversation.vo.UserId;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.NoSuchElementException;

/**
 * 会话管理 API (Updated to use DTOs)
 */
@RestController
@RequestMapping("/api/v1/conversations")
@RequiredArgsConstructor
public class ConversationController {

    private final ConversationService conversationService;

    /**
     * 开始新会话
     *
     * @param request 包含 userId, appId, initialMessage
     * @return 创建的会话概要信息 DTO
     */
    @PostMapping
    public R<ConversationSummaryDTO> startConversation(
            @Validated @RequestBody StartConversationCommand request) {
        return R.ok(conversationService.startConversation(request));
    }

    /**
     * 发送消息
     *
     * @param id             会话ID
     * @param messageRequest 消息内容 DTO
     * @return AI 回复消息 DTO
     */
    @PostMapping(
            value = "/{id}/messages",
            produces = MediaType.TEXT_EVENT_STREAM_VALUE + ";charset=UTF-8")
    public ResponseEntity<Flux<ServerSentEvent<String>>> sendMessage(
            @PathVariable Long id, @Valid @RequestBody SendMessageRequest messageRequest) {
        return ResponseEntity.ok()
                .contentType(MediaType.TEXT_EVENT_STREAM)
                .header("Content-Type", "text/event-stream;charset=UTF-8")
                .body(
                        conversationService
                                .sendMessage(new ConversationId(id), messageRequest)
                                .map(
                                        message ->
                                                ServerSentEvent.<String>builder().data(message.getContent()).build()));
    }

    /**
     * 获取会话详情（含消息）
     *
     * @param id 会话ID (String from path)
     * @return 会话详情 DTO
     */
    @GetMapping("/{id}")
    public R<ConversationDetailDTO> getConversation(@PathVariable Long id) {
        ConversationId conversationId = new ConversationId(id);
        ConversationDetailDTO detailDto =
                conversationService
                        .getConversation(conversationId)
                        .orElseThrow(() -> new NoSuchElementException("Conversation not found: " + id));
        return R.ok(detailDto);
    }

    /**
     * 获取会话列表（概要信息）
     *
     * @param userId 用户ID (从请求参数获取)
     * @param appId  (可选) 应用ID (从请求参数获取)
     * @return 会话概要 DTO 列表
     */
    @GetMapping
    public R<List<ConversationSummaryDTO>> listConversations(
            @RequestParam Long userId, @RequestParam(required = false) Long appId) {
        UserId uid = new UserId(userId);
        AppId aid = (appId != null) ? new AppId(appId) : null;
        List<ConversationSummaryDTO> summaryDtos = conversationService.listConversations(uid, aid);
        return R.ok(summaryDtos);
    }

    /**
     * 删除会话
     *
     * @param id 会话ID (String from path)
     * @return 操作结果
     */
    @DeleteMapping("/{id}")
    public R<Void> deleteConversation(@PathVariable Long id) {
        ConversationId conversationId = new ConversationId(id);
        conversationService.deleteConversation(conversationId);
        return R.ok();
    }
}
